<template>
  <div class="lucky-excel">
    <div class="tool-bar">
      <el-button v-if="showDownload" type="primary" class="tool" plain @click="download">下载</el-button>
      <el-button v-if="showExport" type="primary" class="tool" plain @click="exportFile">导出</el-button>
      <el-upload
          v-if="showImport"
          ref="upload"
          name="file"
          action=""
          :limit="1"
          :before-upload="beforeUpload"
          :show-file-list="false"
      >
        <el-button slot="trigger" type="primary" class="tool" plain>导入excel</el-button>
      </el-upload>
      <el-button v-if="showPrintDefault" v-print="`#${printParam.id}`" type="primary" class="tool" plain @click="printFn(false)">打印</el-button>
      <el-button v-if="showPrint" v-print="`#${printParam.id}`" type="primary" class="tool" plain @click="printFn(true)">打印选中区域</el-button>
    </div>
    <div :id="luckysheetOptions.container" class="container" />
    <div :id="printParam.id" :style="{ textAlign : printPosition }" />
  </div>

</template>

<script>
  import LuckyExcel from 'luckyexcel'
  import exportExcel from '@/util/exportExcel.js'

  export default {
    name: 'EditExcel',
    props: {
      // 显示的excel文件
      file: {
        default: () => {
          return null
        }
      },
      // 打印时base64图片的位置
      printPosition: {
        default: 'center',
        type: String
      },
      showDownload: {
        type: Boolean,
        default: true
      },
      showExport: {
        type: Boolean,
        default: true
      },
      showImport: {
        type: Boolean,
        default: true
      },
      showPrintDefault: {
        type: Boolean,
        default: true
      },
      showPrint: {
        type: Boolean,
        default: true
      }
    },
    data() {
      return {
        // excel基础配置
        luckysheetOptions: {
          // 对应区域
          container: 'editSheet',
          // 语言
          lang: 'zh',
          // 工作簿名称
          title: '',
          // 头部标题栏显示  会被showtoolbarConfig 覆盖
          showinfobar: false,
          // 头部标题栏 配置
          showtoolbarConfig: {
            undoRedo: true, //撤销重做，注意撤消重做是两个按钮，由这一个配置决定显示还是隐藏
            paintFormat: true, //格式刷
            currencyFormat: false, //货币格式
            percentageFormat: false, //百分比格式
            numberDecrease: true, // '减少小数位数'
            numberIncrease: true, // '增加小数位数
            moreFormats: true, // '更多格式'
            font: true, // '字体'
            fontSize: true, // '字号大小'
            bold: true, // '粗体 (Ctrl+B)'
            italic: true, // '斜体 (Ctrl+I)'
            strikethrough: true, // '删除线 (Alt+Shift+5)'
            underline: true, // '下划线 (Alt+Shift+6)'
            textColor: true, // '文本颜色'
            fillColor: true, // '单元格颜色'
            border: true, // '边框'
            mergeCell: true, // '合并单元格'
            horizontalAlignMode: true, // '水平对齐方式'
            verticalAlignMode: true, // '垂直对齐方式'
            textWrapMode: true, // '换行方式'
            textRotateMode: true, // '文本旋转方式'
            image:true, // '插入图片'
            link:false, // '插入链接'
            chart: false, // '图表'（图标隐藏，但是如果配置了chart插件，右击仍然可以新建图表）
            postil:  true, //'批注'
            pivotTable: false,  //'数据透视表'
            function: true, // '公式'
            frozenMode: true, // '冻结方式'
            sortAndFilter: true, // '排序和筛选'
            conditionalFormat: false, // '条件格式'
            dataVerification: true, // '数据验证'
            splitColumn: true, // '分列'
            screenshot: true, // '截图'
            findAndReplace: true, // '查找替换'
            protection:true, // '工作表保护'
            print:false, // '打印'
          },
          // 钩子函数
          hook: {
            // 单元格进入编辑前
            cellEditBefore(area){},
            // 更新这个单元格值之前触发 return false 则不执行后续的更新
            cellUpdateBefore(r,c,value,isRefresh){},
            // 更新单元格后触发
            cellUpdated(r,c,oValue,nValue,isRefresh){},
            // 单元格渲染前触发 return false 则不渲染该单元格
            cellRenderBefore(cell,position,sheet,ctx){},
            // 单元格渲染后触发
            cellRenderAfter(cell,position,sheet,ctx){},
            // 所有单元格渲染之前执行
            cellAllRenderBefore(data,sheet,ctx){},
            // 行标题单元格渲染前触发 return false 则不渲染行标题
            rowTitleCellRenderBefore(rowNum,position,ctx){},
            // 行标题单元格渲染后触发，return false 则不渲染行标题
            rowTitleCellRenderAfter(rowNum,position,ctx){},
            // 列标题单元格渲染前触发，return false 则不渲染列标题
            columnTitleCellRenderBefore(columnAbc,position,ctx){},
            // 列标题单元格渲染后触发，return false 则不渲染列标题
            columnTitleCellRenderAfter(columnAbc,position,ctx){},
            // 还有鼠标的钩子 以及其他的很多钩子   文档地址 https://mengshukeji.gitee.io/LuckysheetDocs/zh/
          }
        },
        // 打印基础配置
        printParam: {
          // 对应区域
          id: 'print_html'
        }
      }
    },
    mounted() {
      if (this.file) {
        this.beforeUpload(this.file)
        return
      }
      // eslint-disable-next-line no-debugger
      this.initExcel()
    },
    methods: {
      /**
       * @description: 初始化excel
       * @author: xhy
       * @param {Object} exportJson 初始化数据
       */
      initExcel(exportJson = {}) {
        // eslint-disable-next-line no-undef
        this.codeFormat(exportJson)
        luckysheet.create({
          ...this.luckysheetOptions,
          data: exportJson.sheets,
        })
      },
      /**
       * 处理符号导入乱码
       * **/
      codeFormat(exportJson){
        // 处理符号导出后再导入的乱码
        exportJson.sheets.forEach(sheet => {
          sheet.celldata.forEach(cell => {
            if(cell.v && cell.v.ct && cell.v.ct.s){
              let val = '';
              if(cell.v.ct.s && cell.v.ct.s.length > 0){
                val = cell.v.ct.s.map(item => item.v).join('');
              }
              cell.v = {
                "ct": {
                  "fa": "@",
                  "t": "s"
                },
                "fs": 10,
                "fc": cell.v.fc,
                "ff": cell.v.ff,
                "ht": cell.v.ht,
                "vt": cell.v.vt,
                "tb": cell.v.tb,
                "v": val,
                "qp": 1
              }
            }
          })
        })
      },
      /**
       * @description: 打印默认区域
       * @author: xhy
       * @param {Boolean} flag 是否默认打印
       */
      printFn(flag) {
        // eslint-disable-next-line no-undef
        const src = flag ? luckysheet.getScreenshot() : luckysheet.getScreenshot({ range: 'A1:J50' })
        const $img = `<img src=${src} style="max-width: 90%;" />`
        this.$nextTick(() => {
          document.querySelector(`#${this.printParam.id}`).innerHTML = $img
        })
      },

      /**
       * @description: 获取在线excel数据后编辑成excel文件导出
       * @author: xhy
       */
      async exportExcel() {
        // eslint-disable-next-line no-undef
        const data = luckysheet.getluckysheetfile()
        console.log(data)
        const exportData = await exportExcel(data)
        const blob = new Blob([exportData])
        const file = new File([blob], this.file?.name || '文档.xlsx', { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
        return file
      },

      /**
       * @description: 导出excel文件对象
       * @author: xhy
       */
      async exportFile() {
        const file = await this.exportExcel()
        this.$emit('exportFile', file)
        this.beforeUpload(file)
      },

      /**
       * @description: 浏览器导出excel
       * @author: xhy
       * @param {Object} blob excel数据，也可以是file对象
       */
      async download() {
        const file = await this.exportExcel()
        if (window.navigator && window.navigator.msSaveBlob) {
          window.navigator.msSaveBlob(file, file.name)
        } else {
          const a = document.createElement('a')
          a.download = file.name
          a.href = URL.createObjectURL(file)
          a.style.display = 'none'
          document.body.appendChild(a)
          a.click()
          document.body.removeChild(a)
        }
      },

      /**
       * @description: 导入excel文件
       * @author: xhy
       * @param {Object} file excel文件
       */
      beforeUpload(file) {
        const suffix = file.name.split('.')
        if (suffix[suffix.length - 1] !== 'xlsx') {
          this.$message.error('文件格式只能是.xlsx')
          return false
        }
        // eslint-disable-next-line no-undef
        luckysheet.destroy()
        // eslint-disable-next-line no-undef
        LuckyExcel.transformExcelToLucky(file, (exportJson) => {
          if (exportJson.sheets == null || exportJson.sheets.length === 0) {
            this.$message.warning('读取excel文件内容失败，目前不支持xls文件!')
            return
          }
          this.initExcel(exportJson)
        })
      }
    }
  }
</script>

<style lang="scss" scoped>
  $height:40px;
  .lucky-excel{
    position:relative;overflow:hidden;width:100%;height:100%;
    .container{
      width:100%;height:calc(100% - #{$height});
    }
    .tool-bar{
      display:flex;width:100%;height: $height;justify-content:left;align-items:center;
      ::v-deep .el-button{
        padding:0 10px;
        height: 30px;
        line-height: 30px;
      }
      .tool{
        margin-left:10px
      }
    }
  }
</style>
